package com.benson.thread.interrupt;

import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public interface CancellableTask<T> extends Callable<T> {

	void cancel();
	RunnableFuture<T> newTask();
}

class CancellingExecutor extends ThreadPoolExecutor{

	public CancellingExecutor(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}

	@Override
	protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
		if(callable instanceof CancellableTask){
			return ((CancellableTask<T>)callable).newTask();
		}else{
			return super.newTaskFor(callable);
		}
	}
	
	
}

abstract class SocketUsiongTask<T> implements CancellableTask<T>{
	private Socket socket;
	
	protected synchronized void setSocket(Socket s){
		socket = s;
	}
	
	public synchronized void cancel(){
		try{
			if(socket != null){
				socket.close();
			}
		}catch (Exception e) {
			
		}
	}
	
	public RunnableFuture<T> newTask(){
		return new FutureTask<T>(this){

			@Override
			public boolean cancel(boolean mayInterruptIfRunning) {
				try{
					SocketUsiongTask.this.cancel();
				}
				finally{
					return super.cancel(mayInterruptIfRunning);
				}		
			}
			
		};
	}
}